package controllers;

import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;

import agency_terminal.data_types.Data;
import agency_terminal.data_types.DataTicketRequest;
import agency_terminal.data_types.DataTicketResponse;
import agency_terminal.data_types.DataUserRequest;
import agency_terminal.data_types.OperationRequest;
import agency_terminal.data_types.OperationResponse;
import agency_terminal.enums.OperationResults;
import agency_terminal.enums.OperationTypes;


import connectors.Agency;


public class TerminalController {
	private static TerminalController instance = null;
	private Agency agencyConnector = null;
	private String ipTerminal = null;
	private Boolean userSession = false;
	
	protected TerminalController(){		
		loadConfiguration();
	}
	
	public static TerminalController getInstance() {
	      if(instance == null) {
	         instance = new TerminalController();
	      }
	      return instance;
	}
	
	private void loadConfiguration(){

		ResourceBundle labels =ResourceBundle.getBundle("terminal");
		
		ipTerminal = labels.getString("TERMINAL_IP");
		
		String hostAgency = labels.getString("AGENCY_HOST");			
		Integer portAgency = new Integer(labels.getString("AGENCY_PORT"));
		Integer timeoutAgency = new Integer(labels.getString("AGENCY_TIMEOUT"));		  		 
		agencyConnector = new Agency(hostAgency, portAgency, timeoutAgency);
		
		System.out.println("Se levanta la configuracion de la terminal");
		System.out.println("TERMINAL_IP" + " => " + ipTerminal);
		System.out.println("AGENCY_HOST" + " => " + hostAgency);
		System.out.println("AGENCY_PORT" + " => " + portAgency);
		System.out.println("AGENCY_TIMEOUT" + " => " + timeoutAgency);		  
	}
	
	public OperationResponse createTicket(String carRegistration, Date dateInit, Integer duration){
		
		//se crea el ticket
		Data data = new DataTicketRequest();
		((DataTicketRequest) data).setCarRegistration(carRegistration);
		((DataTicketRequest) data).setDateInit(dateInit);
		((DataTicketRequest) data).setDuration(duration);
		
		//se validan los datos
		OperationResponse validationResponse = validateTicket(((DataTicketRequest) data));
		
		if(validationResponse.getResult() == OperationResults.ok){			
			//se arma el request
			OperationRequest operationRequest = new OperationRequest(OperationTypes.ticketCreate, data, ipTerminal);
			
			//se consulta a la agencia
			return agencyConnector.executeOperation(operationRequest);			
			
		}else{			
			return validationResponse;
		}		
	}

	
	public OperationResponse cancelTicket(Integer idTicket){
		//se crea el ticket
		Data data = new DataTicketRequest();
		((DataTicketRequest) data).setId(idTicket);
		
		//se arma el request
		OperationRequest operationRequest = new OperationRequest(OperationTypes.ticketCancel, data, ipTerminal);
		
		//se consulta a la agencia
		return agencyConnector.executeOperation(operationRequest);						
	}	
	
	
	public OperationResponse loginUser(String user, String password){
		//se crea el ticket
		Data data = new DataUserRequest();
		((DataUserRequest) data).setUser(user);
		((DataUserRequest) data).setPassword(password);
				
		//se arma el request
		OperationRequest operationRequest = new OperationRequest(OperationTypes.userLogin, data, ipTerminal);
		
		//se consulta a la agencia
		return agencyConnector.executeOperation(operationRequest);			
	}
	
	public boolean existUserSession(){
		return userSession;
	}
	
	public void setUserSession(){
		userSession = true;
	}
	
	public void destroyUserSession(){
		userSession = false;		
	}
		
	private OperationResponse validateTicket(DataTicketRequest dataTicket){
		//TODO: hay que determinar las reglas de validacion
		String message = "";
		OperationResults result = OperationResults.ok;
		
		if(dataTicket.getCarRegistration().trim().length() == 0){
			message = "La matricula no puede ser nula. ";
			result = OperationResults.error;
		}
		
		Calendar actual_date = Calendar.getInstance();
		actual_date.set(Calendar.MINUTE, 0);
		actual_date.set(Calendar.SECOND, 0);
		if(dataTicket.getDateInit().compareTo(actual_date.getTime()) < 0){
			message += "La fecha/hora inicial no puede ser menor que la fecha/hora actual. ";
			result = OperationResults.error;
		}
		
		OperationResponse response = new OperationResponse(result, message, null);
		return response;
	}
	
	
	/****************************************************************************************************/
	
	public static void main(String[] args) {
		TerminalController terminalController = TerminalController.getInstance();
		
		OperationResponse operationResponse = terminalController.createTicket("SAF-2000", new Date(), 30);
		System.out.println("Recibimos la respuesta del servidor: " + operationResponse.getResult() + " - " + operationResponse.getResultMessage());
		DataTicketResponse dataResponse = (DataTicketResponse) operationResponse.getData();
		System.out.println("El valor del ticket es: " + dataResponse.getValue());		

		operationResponse = terminalController.cancelTicket(1000);		
		System.out.println("Recibimos la respuesta del servidor: " + operationResponse.getResult() + " - " + operationResponse.getResultMessage());
		dataResponse = (DataTicketResponse) operationResponse.getData();
		System.out.println("El id de anulacion es: " + dataResponse.getIdCancellation());
		
		operationResponse = terminalController.loginUser("pablo", "rodriguez");		
		System.out.println("Recibimos la respuesta del servidor: " + operationResponse.getResult() + " - " + operationResponse.getResultMessage());		
	}
}
